// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

import GlobalManagerController from "../GlobalManagerController";
import ToastController from "../ToastController";
import { AudioManager } from "./AudioManager";
import { Config } from "./Config";

const { ccclass, property } = cc._decorator;


export class Tools {

    static setTouchEvent(peopleNode: cc.Node, startFunction?: Function, endFunction?: Function, cancelFunction?: Function) {
        this.setTouchEventParent(peopleNode, true, startFunction, endFunction, cancelFunction)
    }
    static setGameTouchEvent(peopleNode: cc.Node, startFunction?: Function, endFunction?: Function, cancelFunction?: Function) {
        this.setTouchEventParent(peopleNode, false, startFunction, endFunction, cancelFunction)
    }

    //添加点击事件 
    //isSound 是否需要按键音效，大厅的都需要 游戏内有自己的按键音所以不需要
    //peopleNode 节点
    //startFunction 按下事件
    //endFunction 抬起事件
    //cancelFunction 取消事件
    private static setTouchEventParent(peopleNode: cc.Node, isSound: boolean, startFunction?: Function, endFunction?: Function, cancelFunction?: Function) {
        peopleNode.on(cc.Node.EventType.TOUCH_START, (event: cc.Event.EventTouch) => {
            if (isSound) {
                AudioManager.keyingToneAudio();
            }

            if (startFunction != null) {
                startFunction(peopleNode, event);
            }
        }, this);
        peopleNode.on(cc.Node.EventType.TOUCH_END, (event: cc.Event.EventTouch) => {
            if (endFunction != null) {
                endFunction(peopleNode, event);
            }
        }, this);
        peopleNode.on(cc.Node.EventType.TOUCH_CANCEL, (event: cc.Event.EventTouch) => {
            if (cancelFunction != null) {
                cancelFunction(peopleNode, event);
            }
        }, this);
    }

    static cancelTouchStartListener(peopleNode: cc.Node) {
        peopleNode.off(cc.Node.EventType.TOUCH_START, this);
    }
    static cancelTouchEndListener(peopleNode: cc.Node) {
        peopleNode.off(cc.Node.EventType.TOUCH_END, this);
    }
    static cancelTouchCancelListener(peopleNode: cc.Node) {
        peopleNode.off(cc.Node.EventType.TOUCH_CANCEL, this);
    }

    //为精灵添加图片
    static setNodeSpriteFrame(node: cc.Node, path: string) {
        cc.resources.load(path, cc.SpriteFrame, function (error: Error, assets: cc.SpriteFrame) {
            const sprite = node.getComponent(cc.Sprite);
            sprite.spriteFrame = assets;
        });
    }

    //添加网络图片
    static setNodeSpriteFrameUrl(node: cc.Node, url: string) {
       

        if (!node) {
            console.error("setNodeSpriteFrameUrl: node 参数为空");
            return;
        }

        let avatarSp = node.getComponent(cc.Sprite);
        if (!avatarSp) {
            console.error("setNodeSpriteFrameUrl: 节点没有 cc.Sprite 组件", node.name);
            return;
        }

        if (url == null || url == '') {
            console.warn("setNodeSpriteFrameUrl: URL为空，跳过加载");
            return;
        }

       

        // 保存原有的材质，避免圆形遮罩丢失
        const originalMaterial = avatarSp.getMaterial(0);

        cc.assetManager.loadRemote(url, { ext: '.png' }, (err, texture: cc.Texture2D) => {
            if (err) {
                console.error("加载远程图片失败：", err.message || err, "URL:", url);
                return;
            }

          
            texture.setPremultiplyAlpha(true);  
            texture.packable = false;//加载圆头像的时候 必须关闭合图

            // 创建新的SpriteFrame并设置
            avatarSp.spriteFrame = new cc.SpriteFrame(texture);

            // 恢复原有的材质（保持圆形遮罩效果）
            if (originalMaterial) {
                avatarSp.setMaterial(0, originalMaterial);
               
            }

          
        });
    }

    //红色按钮
    static redButton(node: cc.Node, click?: Function, label?: string) {
        Tools.buttonState(node, Config.btnRedNormal, Config.btnRedPressed, Config.btnRedNormalColor, Config.btnRedPressedColor, click, label);
    }
    //绿色按钮
    static greenButton(node: cc.Node, click?: Function, label?: string) {
        Tools.buttonState(node, Config.btnGreenNormal, Config.btnGreenPressed, Config.btnGreenNormalColor, Config.btnGreenPressedColor, click, label);
    }
    //黄色按钮
    static yellowButton(node: cc.Node, click?: Function, label?: string) {
        Tools.buttonState(node, Config.btnYellowNormal, Config.btnYellowPressed, Config.btnYellowNormalColor, Config.btnYellowPressedColor, click, label);
    }
    //灰色按钮
    static grayButton(node: cc.Node, click?: Function, label?: string) {
        Tools.buttonState(node, Config.btnGrayNormal, Config.btnGrayNormal, Config.btnGrayNormalColor, Config.btnGrayNormalColor, click, label);
    }


    //通用的按钮点击事件，带点击变颜色的
    static buttonState(node: cc.Node, normalImg: string, pressedImg: string, normalColor: string, pressedColor: string, click?: Function, labelText?: string) {

        let btnGreen = node.getChildByName('btn_color_normal');//获取按钮背景节点
        let btnLabel = node.getChildByName('button_label');//获取按钮文字节点

        let label = btnLabel.getComponent(cc.Label);
        let labelOutline = btnLabel.getComponent(cc.LabelOutline);

        if (labelText != null) {
            label.string = labelText
        }

        Tools.setTouchEvent(btnGreen, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, pressedImg);
            label.fontSize = 34;
            label.lineHeight = 34
            let color = new cc.Color();
            cc.Color.fromHEX(color, pressedColor);
            labelOutline.color = color;
            btnLabel.color = cc.Color.fromHEX(new cc.Color(), '#B3B3B3');


        }, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, normalImg);
            label.fontSize = 36;
            label.lineHeight = 36
            let color = new cc.Color();
            cc.Color.fromHEX(color, normalColor);
            labelOutline.color = color;
            btnLabel.color = cc.Color.fromHEX(new cc.Color(), '#FFFFFF');
            if (click != null) {
                click();
            }
        }, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, normalImg);
            label.fontSize = 36;
            label.lineHeight = 36
            let color = new cc.Color();
            cc.Color.fromHEX(color, normalColor);
            labelOutline.color = color;
            btnLabel.color = cc.Color.fromHEX(new cc.Color(), '#FFFFFF');
        });
    }

    //点击变颜色的图片按钮
    static imageButtonClick(node: cc.Node, normalImg: string, pressedImg: string, click: Function) {
        Tools.setTouchEvent(node, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, pressedImg);
        }, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, normalImg);
            click()
        }, (node: cc.Node) => {
            Tools.setNodeSpriteFrame(node, normalImg);
        });
    }

    //格式化资金显示格式的
    static NumToTBMK(num: number, digit: number = 1, min: number = 10000): string {
        let intNum = num;
        if (intNum < min) {
            return intNum.toString();
        }

        let unitStrArr = ["T", "B", "M", "K"];
        let unitArr = [Math.pow(10, 12), Math.pow(10, 9), Math.pow(10, 6), Math.pow(10, 3)];
        for (let i = 0; i < unitArr.length; ++i) {
            let result = intNum / unitArr[i];
            if (result >= 1) {
                let str = result.toString();
                let strArr = str.split(".");
                let suffix = strArr[1] ?? "";
                if (suffix.length >= digit) {
                    if (digit == 0) {
                        return strArr[0] + unitStrArr[i];
                    }
                    return strArr[0] + "." + suffix.substring(0, digit) + unitStrArr[i];
                }
                else {
                    let fillStr = new Array(digit - suffix.length).fill("0").join("");
                    return strArr[0] + "." + suffix + fillStr + unitStrArr[i];
                }
            }
        }
    }

    static getCurrentTimeWithMilliseconds(): string {
        const currentDate = new Date();
        const year = currentDate.getFullYear();
        const month = String(currentDate.getMonth() + 1).padStart(2, '0');
        const day = String(currentDate.getDate()).padStart(2, '0');
        const hours = String(currentDate.getHours()).padStart(2, '0');
        const minutes = String(currentDate.getMinutes()).padStart(2, '0');
        const seconds = String(currentDate.getSeconds()).padStart(2, '0');
        const milliseconds = String(currentDate.getMilliseconds()).padStart(3, '0');

        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
    }

    //赋值文本到剪切板
    public static copyText(textToCopy: string, cb?: Function): void {
        // 退回到使用 document.execCommand（旧版浏览器）
        const input = document.createElement('input');
        input.setAttribute('value', textToCopy);
        document.body.appendChild(input);

        // 选择文本并复制
        input.select();
        input.setSelectionRange(0, input.value.length); // 兼容移动端

        try {
            const successful = document.execCommand('copy');
            if (successful) {
                console.log("文本已复制到剪贴板！");
                cb && cb(true);
            } else {
                console.error("复制失败：execCommand 返回 false");
                cb && cb(false);
            }
        } catch (err) {
            console.error("复制失败：", err);
            cb && cb(false);
        }

        // 删除临时 input 元素
        document.body.removeChild(input);
    }

    //拆分数组用的，一个长度为 10 的数组 拆分成 2 个长度为 5 的数组 chunkArray(user_s, 5)
    static chunkArray<T>(arr: T[], chunkSize: number): T[][] {
        const result: T[][] = [];
        for (let i = 0; i < arr.length; i += chunkSize) {
            result.push(arr.slice(i, i + chunkSize));
        }
        return result;
    }
    //设置倒计时的秒数的位置
    static setCountDownTimeLabel(buttonNode: cc.Node) {
        let btn = buttonNode.getChildByName('button_label')
        let timeBtn = buttonNode.getChildByName('buttonLabel_time')
        let xPos = btn.position.x + btn.width / 2 + timeBtn.width / 2
        timeBtn.setPosition(xPos, 0)
    }

     //缩放+变暗按压效果的按钮
    static scaleButtonClick(node: cc.Node, click: Function) {
        // 保存原始状态
        const originalScale = node.scale;
        const originalColors = new Map<cc.Node, cc.Color>();
        
        // 递归保存节点及其所有子节点的原始颜色
        const saveOriginalColors = (targetNode: cc.Node) => {
            originalColors.set(targetNode, targetNode.color.clone());
            targetNode.children.forEach(child => {
                saveOriginalColors(child);
            });
        };
        
        // 递归设置节点及其所有子节点的颜色
        const setNodeColors = (targetNode: cc.Node, color: cc.Color) => {
            targetNode.color = color;
            targetNode.children.forEach(child => {
                setNodeColors(child, color);
            });
        };
        
        // 递归恢复节点及其所有子节点的原始颜色
        const restoreOriginalColors = (targetNode: cc.Node) => {
            const originalColor = originalColors.get(targetNode);
            if (originalColor) {
                targetNode.color = originalColor;
            }
            targetNode.children.forEach(child => {
                restoreOriginalColors(child);
            });
        };
        
        // 保存所有节点的原始颜色
        saveOriginalColors(node);
        
        Tools.setTouchEvent(node, (node: cc.Node) => {
            // 按下时：缩放到0.95，所有节点颜色变暗到180（约70%亮度）
            cc.tween(node)
                .to(0.1, { 
                    scaleX: originalScale * 0.95, 
                    scaleY: originalScale * 0.95 
                }, { easing: 'quadOut' })
                .start();
            
            setNodeColors(node, cc.color(180, 180, 180));
        }, (node: cc.Node) => {
            // 抬起时：恢复原始缩放和颜色，然后执行点击回调
            cc.tween(node)
                .to(0.1, { 
                    scaleX: originalScale, 
                    scaleY: originalScale 
                }, { easing: 'backOut' })
                .start();
            
            restoreOriginalColors(node);
            
            if (click) {
                click();
            }
        }, (node: cc.Node) => {
            // 取消时：恢复原始状态
            cc.tween(node)
                .to(0.1, { 
                    scaleX: originalScale, 
                    scaleY: originalScale 
                }, { easing: 'quadOut' })
                .start();
            
            restoreOriginalColors(node);
        });
    }

    //赋值文本到剪切板
    static copyToClipboard(text: string) {
        const textarea = document.createElement('textarea');
        textarea.style.position = 'fixed';
        textarea.style.opacity = '0';
        textarea.value = text;
        document.body.appendChild(textarea);
        textarea.select();
        try {
            const successful = document.execCommand('copy');
            if (successful) {
                console.log('文本已复制到剪切板');
                // 成功提示（多语言）
                // @ts-ignore
                const msg = typeof window.getLocalizedStr === 'function' ? window.getLocalizedStr('CopySuccess') : 'Copy success';
                this.showToast(msg);
            } else {
                console.error('复制到剪切板失败');
                // 失败提示（多语言）
                // @ts-ignore
                const msg = typeof window.getLocalizedStr === 'function' ? window.getLocalizedStr('CopyFailed') : 'Copy failed';
                this.showToast(msg);
            }
        } catch (err) {
            console.error('复制到剪切板失败：', err);
            // @ts-ignore
            const msg = typeof window.getLocalizedStr === 'function' ? window.getLocalizedStr('CopyFailed') : 'Copy failed';
            this.showToast(msg);
        }
        document.body.removeChild(textarea);
    }
     // 显示全局 Toast 提示
    private static showToast(content: string) {
        try {
            // 查找挂载了 GlobalManagerController 的节点（一般在 Canvas 上）
            const canvas = cc.find('Canvas');
            if (!canvas) {
                cc.warn('Canvas 节点未找到，无法显示 Toast');
                return;
            }
            const gm = canvas.getComponent(GlobalManagerController);
            if (gm && gm.toastController) {
                gm.toastController.showContent(content);
                return;
            }

            // 兜底：直接在 Canvas 子节点中查找任意一个 ToastController
            const toast = canvas.getComponentInChildren(ToastController);
            if (toast) {
                toast.showContent(content);
                return;
            }

            cc.warn('未找到可用的 ToastController 组件');
        } catch (e) {
            cc.warn('显示 Toast 失败: ', e);
        }
    }
}
